#include "Socket.h"

#include <iostream>
#include <assert.h>

Socket::Socket()
{
	m_socket = nullptr;
	m_socketSet = SDLNet_AllocSocketSet(1);
}

Socket::Socket(const TCPsocket& s)
{
	m_socket = s;
	m_socketSet = SDLNet_AllocSocketSet(1);
	if (m_socket)
	{
		SDLNet_TCP_AddSocket(m_socketSet, m_socket);
	}
}

Socket::~Socket()
{
	SDLNet_TCP_DelSocket(m_socketSet, m_socket);
	SDLNet_TCP_Close(m_socket);
	SDLNet_FreeSocketSet(m_socketSet);
}

bool Socket::Send(const SocketMessage& sm)
{
	//int result = SDLNet_TCP_Send(m_socket, sm.GetData(), sm.GetLength());
	//if (result <= 0)
	//{
	//	std::cout << "error: " << SDL_GetError() << std::endl;
	//	return false;
	//}
	//else
	//{
	//	return true;
	//}	
	//return (result <= 0);
	
	assert(m_socket);

	int len = sm.GetLength();
	const unsigned char* data = sm.GetData();
	
	int result = SDLNet_TCP_Send(m_socket, data, len);
	if (result != len)
	{
		//std::cout << "failed to send data: " << SDLNet_GetError() << std::endl;
		return false;
	}
	//std::cout << "data sent";
	//std::cout << std::endl;

	return true;
}

bool Socket::Receive(SocketMessage* sm)
{
	assert(m_socket);

	const int len = 200;
	unsigned char msg[len];
	memset(msg, 0, len);

	while(HasData())
	{
		int result = SDLNet_TCP_Recv(m_socket, msg, len);
		if (result <= 0)
		{
			//std::cout << "failed to receive message" << std::endl;
			return false;
		}
		else
		{
			//std::cout << "Got data: " << msg << std::endl;

			sm->Append(msg, msg + result);
		}
	}
	//while(true)
	//{
	//	int result = SDLNet_TCP_Recv(m_socket, msg, len);
	//	if (result > len)
	//	{
	//		std::cout << "received data" << std::endl;
	//		// add to a bigger array
	//		char msgs[len * 2];

	//	}
	//	else if (result > 0)
	//	{
	//		std::cout << "received data" << std::endl;

	//		msg[result] = 0;
	//		//sm->WriteInt((int)msg);
	//		return true;
	//	}

	//	if (result < 0)
	//	{
	//		std::cout << "failed to receive data" << std::endl;
	//		return false;
	//	}
	//}
	//return false;
	return true;
}

bool Socket::Close()
{
	SDLNet_TCP_Close(m_socket);

	return true;
}

bool Socket::HasData()
{
	int numReady = 0;
	if (m_socket)
	{
		numReady = SDLNet_CheckSockets(m_socketSet, 10);
	}
	return (numReady != 0);
}

bool Socket::IsOpen()
{
	int i = SDLNet_SocketReady(m_socket);
	return (i >= 0);
}

//bool Socket::AddSocket(const Socket& socket)
//{
//	return true;
//}

TCPsocket& Socket::GetSocket()
{
	return m_socket;
}